package com.ubxtech.gateway.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.cloud.nacos.NacosPropertySourceRepository;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.cloud.nacos.client.NacosPropertySource;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.ubxtech.core.dto.LoginAppSecretConfig;
import com.ubxtech.core.utils.SpringUtils;
import com.ubxtech.gateway.properties.CustomGatewayProperties;
import com.ubxtech.nacos.listener.ServiceDiscoveryListenerBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;

import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * 监听服务上下线
 * @author Victor.Xiao
 * @since 2023-09-05 14:53
 **/
@Slf4j
@Component
public class ServiceEventListener implements ApplicationListener<ApplicationReadyEvent> {

    @Resource
    private NacosServiceManager nacosServiceManager;
    @Resource
    private NacosConfigManager nacosConfigManager;
    @Resource
    private CustomGatewayProperties customGatewayProperties;

    @Resource
    private NacosConfigProperties nacosConfigProperties;


    @Override
    public void onApplicationEvent(@NotNull ApplicationReadyEvent event) {

        try {
            NamingService namingService = nacosServiceManager.getNamingService();
            if (StrUtil.isBlank(customGatewayProperties.getUpDownServiceId())) {
                return;
            }
            //监听上下线
            namingService.subscribe(customGatewayProperties.getUpDownServiceId(),nacosConfigProperties.getGroup(), ServiceDiscoveryListenerBuilder.buildEventListener());
            //监听配置变化
            List<NacosPropertySource> list = NacosPropertySourceRepository.getAll();
            List<String> sharedConfigDataIds = null;
            if (CollectionUtil.isNotEmpty(nacosConfigProperties.getSharedConfigs())) {
                sharedConfigDataIds = nacosConfigProperties.getSharedConfigs().stream().map(NacosConfigProperties.Config::getDataId).collect(Collectors.toList());
            }
            String curDataId = SpringUtils.getApplicationName();
            for (NacosPropertySource propertySource : list) {
                String dataId = propertySource.getDataId();
                //cml-cloud-crms-gateway.yml  cml-cloud-shared.properties cml-cloud-crms-gateway-dev.yml cml-cloud-crms-gateway
                //目前配置监听 cml-cloud-shared会5秒刷新一次 原因未知,待排查,先去掉share订阅
                if (StrUtil.isBlank(dataId) || StrUtil.isBlank(curDataId) || !dataId.contains(curDataId)) {
                    continue;
                }
                //目前配置监听 cml-cloud-shared会5秒刷新一次 原因未知,待排查,先去掉share订阅
                if (CollectionUtil.isNotEmpty(sharedConfigDataIds) && sharedConfigDataIds.contains(dataId)) {
                    continue;
                }
                nacosConfigManager.getConfigService().addListener(propertySource.getDataId(), nacosConfigProperties.getGroup(), new Listener() {
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }

                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        log.info("配置文件变更:{}",dataId);
                        Yaml yaml = new Yaml();
                        Map<String, Object> yamlMap = yaml.load(configInfo);
                        if (CollectionUtil.isEmpty(yamlMap)) {
                            return;
                        }
                        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(yamlMap));
                        JSONObject ubxtechObject = jsonObject.getJSONObject("ubxtech");
                        if (ubxtechObject == null) {
                            return;
                        }
                        JSONObject gatewayObject = ubxtechObject.getJSONObject("gateway");
                        if (gatewayObject == null) {
                            return;
                        }
                        JSONArray appSecretConfigsArr = gatewayObject.getJSONArray("appSecretConfigs");
                        if (appSecretConfigsArr == null) {
                            return;
                        }
                        List<LoginAppSecretConfig> appSecretConfigs = appSecretConfigsArr.toJavaList(LoginAppSecretConfig.class);
                        if (CollectionUtil.isEmpty(appSecretConfigs)) {
                            return;
                        }
                        AppSecretConfigUtil.setAppSecretMap(appSecretConfigs);
                    }
                });
            }
        } catch (NacosException e) {
            log.error("监听nacos配置有误",e);
        }

    }


}
